﻿using System;
using System.Reflection;
using MySql.Simple.Mapper.Attributes;
using MySql.Simple.Mapper.Structures;
using MySql.Simple.Mapper.Types;

namespace MySql.Simple.Mapper.Finders
{
    /// <summary>
    /// Finds the SQL column names to store a classes data in.
    /// </summary>
    public static class ColumnFinder
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ColumnFinder"/> class.
        /// </summary>
        static ColumnFinder()
        {
            TypeMapper = new TypeMapper();
        }

        /// <summary>
        /// Gets or sets the type mapper.
        /// </summary>
        /// <value>The type mapper.</value>
        public static TypeMapper TypeMapper { get; set; }

        /// <summary>
        /// Finds the SQL column names to store a classes data in.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns></returns>
        public static string FindColumn(PropertyInfo target)
        {
            var columnName = string.Empty;

            var attributes = target.GetCustomAttributes(typeof(ColumnAttribute), true);

            foreach (var attribute in attributes)
            {
                var columnAttribute = (ColumnAttribute)attribute;

                columnName = columnAttribute.Name;

                if (!string.IsNullOrEmpty(columnName)) continue;

                columnName = target.Name;

                // Convert to underscored
                columnName = Inflector.Underscore(columnName);
            }

            return columnName;
        }
      
        public static ColumnCollection Find(Type type)
        {
            return Find(type, null);
        }

        public static ColumnCollection Find(Type type, object target)
        {
            var columns = new ColumnCollection();

            var properties = type.GetProperties();
            
            var tableName = TableNameFinder.Find(type);

            var lastColumnName = string.Empty;

            foreach (var property in properties)
            {
                var column = TypeMapper.Map(property);

                // Don't add columns without a column attribute
                if (column == null) continue;

                // Set first/last/table properties
                column.After = lastColumnName;
                column.IsFirst = string.IsNullOrEmpty(lastColumnName);
                column.TableName = tableName;
                column.PropertyName = property.Name;

                // Set value
                if (target != null) column.Value = property.GetValue(target, null);

                // Add column to collection
                columns.Add(column);

                // Set last column name
                lastColumnName = column.Name;
            }

            return columns;
        }

    }
}